package cn.sgy.infrastructure.file.strategy.impl;

import cn.hutool.core.text.StrPool;
import cn.sgy.infrastructure.file.entity.File;
import cn.sgy.infrastructure.file.properties.FileStoreProperties;
import cn.sgy.infrastructure.file.strategy.AbstractFileStore;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.ObjectMetadata;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.net.URLEncoder;

/**
 * @author sgy
 * @description 阿里云OSS存储
 * @date 2023-11-17
 */
@Slf4j
@NoArgsConstructor
@AllArgsConstructor
public class OssFileStore extends AbstractFileStore {
    @Resource
    private OSS oss;
    @Resource
    private FileStoreProperties fileStoreProperties;

    @SneakyThrows
    @Override
    public void doUpload(File file, MultipartFile mf) {
        // 基本信息获取
        String bucketName = fileStoreProperties.getOss().getBucketName();
        String endpoint = fileStoreProperties.getOss().getEndpoint();
        // 构建元数据对象
        ObjectMetadata om = buildObjectMetadata(file);
        // 上传文件
        oss.putObject(bucketName, file.getFileName(), mf.getInputStream(), om);
        // 完善File对象信息
        file.setUrl(getOssFileUrl(bucketName, endpoint, file.getFileName()));
    }

    /**
     * 构建元数据对象
     *
     * @param file file
     * @return 元数据对象
     */
    @SneakyThrows
    private ObjectMetadata buildObjectMetadata(File file) {
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentDisposition("attachment;fileName=" + URLEncoder.encode(file.getSubmittedFileName(), "UTF-8"));
        objectMetadata.setContentType(file.getContentType());
        return objectMetadata;
    }

    /**
     * 拼接阿里云OSS访问得前缀
     *
     * @param bucketName       bucketName
     * @param host             host
     * @param relativeFileName 存储到OSS上的完整地址加文件名
     * @return oss图片访问路径
     */
    private static String getOssFileUrl(String bucketName, String host, String relativeFileName) {
        return "https://" + bucketName + StrPool.DOT + host + StrPool.SLASH + relativeFileName;
    }
}
